home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / MATHS / PLPLOT / PLPLOT.ZIP / examples / C / tutor.c next >
Encoding:
C/C++ Source or Header  |  1994-07-13  |  7.8 KB  |  293 lines

  1. /* $Id: tutor.c,v 1.7 1994/07/12 19:17:31 mjl Exp $
  2.  * $Log: tutor.c,v $
  3.  * Revision 1.7  1994/07/12  19:17:31  mjl
  4.  * Minor cleaning up.
  5.  *
  6.  * Revision 1.6  1994/03/30  07:21:43  mjl
  7.  * Changes to all C example programs: special handling for malloc re: header
  8.  * files eliminated, include of stdio.h and stdlib.h eliminated (now done
  9.  * by plplot.h), include of "plplot.h" changed to <plplot.h> to enable
  10.  * simpler builds by the general user, some cleaning up also.
  11. */
  12.  
  13. /*
  14.  * tutor.c
  15.  * Tony Richardson
  16.  *
  17.  * This program is intended to be used as a template for creating simple
  18.  * two-dimensional plotting programs which use the Plplot plotting
  19.  * library.  The program was written with an emphasis on trying to clearly
  20.  * illustrate how to use the Plplot library functions.  
  21.  *
  22.  * This program reads data for M lines with N points each from an input
  23.  * data file and plots them on the same graph using different symbols.  It
  24.  * draws axes with labels and places a title at the top of the figure.  A
  25.  * legend is drawn to the right of the figure.  The input data file must
  26.  * have the following format:
  27.  *
  28.  *    M        N
  29.  *    x[1]     y[1][1]     y[1][2]     .     .     .     y[1][M]
  30.  *    x[2]     y[2][1]     y[2][2]     .     .     .     y[2][M]
  31.  *    x[3]     y[3][1]     y[3][2]     .     .     .     y[3][M]
  32.  *     .          .           .        .     .     .        .
  33.  *     .          .           .        .     .     .        .
  34.  *     .          .           .        .     .     .        .
  35.  *    x[N]     y[N][1]     y[N][2]     .     .     .     y[N][M]
  36.  *
  37.  * (The first line contains the integer values M and N.  The succeeding
  38.  * N lines contain the x-coordinate and the corresponding y-coordinates
  39.  * of each of the M lines.) 
  40.  */
  41.  
  42. #include "plplot.h"
  43.  
  44. static int
  45. error(char *str);
  46.  
  47. /*
  48.  * You can select a different set of symbols to use when plotting the
  49.  * lines by changing the value of OFFSET. 
  50.  */
  51.  
  52. #define OFFSET  2
  53.  
  54. int
  55. main(int argc, char *argv[])
  56. {
  57.     /* ==============  Begin variable definition section. ============= */
  58.  
  59.     /*
  60.      * i, j, and k are counting variables used in loops and such. M is the
  61.      * number of lines to be plotted and N is the number of sample points
  62.      * for each line.
  63.      */
  64.  
  65.     int i, j, k, M, N, leglen;
  66.  
  67.     /*
  68.      * x is a pointer to an array containing the N x-coordinate values.  y
  69.      * points to an array of M pointers each of which points to an array
  70.      * containing the N y-coordinate values for that line.
  71.      */
  72.  
  73.     PLFLT *x, **y;
  74.  
  75.     /* Define storage for the min and max values of the data. */
  76.  
  77.     float xmin, xmax, ymin, ymax, xdiff, ydiff;
  78.  
  79.     /* Define storage for the filename and define the input file pointer. */
  80.  
  81.     char filename[80], string[80], tmpstr[80];
  82.     FILE *datafile;
  83.  
  84.     /* Here are the character strings that appear in the plot legend. */
  85.  
  86.     static char *legend[] =
  87.     {
  88.     "Aardvarks",
  89.     "Gnus",
  90.     "Llamas",
  91.     NULL};            /* Make sure last element is NULL */
  92.  
  93.     /* ==============  Read in data from input file. ============= */
  94.  
  95. /* Parse and process command line arguments */
  96.  
  97.     (void) plParseInternalOpts(&argc, argv, PL_PARSE_FULL);
  98.  
  99.     /* First prompt the user for the input data file name */
  100.  
  101.     printf("Enter input data file name. ");
  102.     scanf("%s", filename);
  103.  
  104.     /* and open the file. */
  105.  
  106.     datafile = fopen(filename, "r");
  107.     if (datafile == NULL)    /* error opening input file */
  108.     error("Error opening input file.");
  109.  
  110.     /* Read in values of M and N */
  111.  
  112.     k = fscanf(datafile, "%d %d", &M, &N);
  113.     if (k != 2)            /* something's wrong */
  114.     error("Error while reading data file.");
  115.  
  116.     /* Allocate memory for all the arrays. */
  117.  
  118.     x = (float *) malloc(N * sizeof(float));
  119.     if (x == NULL)
  120.     error("Out of memory!");
  121.     y = (float **) malloc(M * sizeof(float *));
  122.     if (y == NULL)
  123.     error("Out of memory!");
  124.     for (i = 0; i < M; i++) {
  125.     y[i] = (float *) malloc(N * sizeof(float));
  126.     if (y[i] == NULL)
  127.         error("Out of memory!");
  128.     }
  129.  
  130.     /* Now read in all the data. */
  131.  
  132.     for (i = 0; i < N; i++) {    /* N points */
  133.     k = fscanf(datafile, "%f", &x[i]);
  134.     if (k != 1)
  135.         error("Error while reading data file.");
  136.     for (j = 0; j < M; j++) {    /* M lines */
  137.         k = fscanf(datafile, "%f", &y[j][i]);
  138.         if (k != 1)
  139.         error("Error while reading data file.");
  140.     }
  141.     }
  142.  
  143.     /* ==============  Graph the data. ============= */
  144.  
  145.     /* Set graph to portrait orientation. (Default is landscape.) */
  146.     /* (Portrait is usually desired for inclusion in TeX documents.) */
  147.  
  148.     plsori(1);
  149.  
  150. /* Initialize plplot */
  151.  
  152.     plinit();
  153.  
  154.     /* 
  155.      * We must call pladv() to advance to the first (and only) subpage.
  156.      * You might want to use plenv() instead of the pladv(), plvpor(),
  157.      * plwind() sequence.
  158.      */
  159.  
  160.     pladv(0);
  161.  
  162.     /*
  163.      * Set up the viewport.  This is the window into which the data is
  164.      * plotted.  The size of the window can be set with a call to
  165.      * plvpor(), which sets the size in terms of normalized subpage
  166.      * coordinates.  I want to plot the lines on the upper half of the
  167.      * page and I want to leave room to the right of the figure for
  168.      * labelling the lines. We must also leave room for the title and
  169.      * labels with plvpor().  Normally a call to plvsta() can be used
  170.      * instead.
  171.      */
  172.  
  173.     plvpor(0.15, 0.70, 0.5, 0.9);
  174.  
  175.     /*
  176.      * We now need to define the size of the window in user coordinates.
  177.      * To do this, we first need to determine the range of the data
  178.      * values.
  179.      */
  180.  
  181.     xmin = xmax = x[0];
  182.     ymin = ymax = y[0][0];
  183.     for (i = 0; i < N; i++) {
  184.     if (x[i] < xmin)
  185.         xmin = x[i];
  186.     if (x[i] > xmax)
  187.         xmax = x[i];
  188.     for (j = 0; j < M; j++) {
  189.         if (y[j][i] < ymin)
  190.         ymin = y[j][i];
  191.         if (y[j][i] > ymax)
  192.         ymax = y[j][i];
  193.     }
  194.     }
  195.  
  196.     /* 
  197.      * Now set the size of the window. Leave a small border around the
  198.      * data.
  199.      */
  200.  
  201.     xdiff = (xmax - xmin) / 20.;
  202.     ydiff = (ymax - ymin) / 20.;
  203.     plwind(xmin - xdiff, xmax + xdiff, ymin - ydiff, ymax + ydiff);
  204.  
  205.     /* 
  206.      * Call plbox() to draw the axes (see the PLPLOT manual for
  207.      * information about the option strings.)
  208.      */
  209.  
  210.     plbox("bcnst", 0.0, 0, "bcnstv", 0.0, 0);
  211.  
  212.     /* 
  213.      * Label the axes and title the graph.  The string "#gm" plots the
  214.      * Greek letter mu, all the Greek letters are available, see the
  215.      * Plplot manual.
  216.      */
  217.  
  218.     pllab("Time (weeks)", "Height (#gmparsecs)", "Specimen Growth Rate");
  219.  
  220.     /*
  221.      * Plot the data.  plpoin() draws a symbol at each point.  plline()
  222.      * connects all the points.
  223.      */
  224.  
  225.     for (i = 0; i < M; i++) {
  226.     plpoin(N, x, y[i], i + OFFSET);
  227.     plline(N, x, y[i]);
  228.     }
  229.  
  230.     /*
  231.      * Draw legend to the right of the chart.  Things get a little messy
  232.      * here.  You may want to remove this section if you don't want a
  233.      * legend drawn.  First find length of longest string.
  234.      */
  235.  
  236.     leglen = 0;
  237.     for (i = 0; i < M; i++) {
  238.     if (legend[i] == NULL)
  239.         break;
  240.     j = strlen(legend[i]);
  241.     if (j > leglen)
  242.         leglen = j;
  243.     }
  244.  
  245.     /* 
  246.      * Now build the string.  The string consists of an element from the
  247.      * legend string array, padded with spaces, followed by one of the
  248.      * symbols used in plpoin above.
  249.      */
  250.  
  251.     for (i = 0; i < M; i++) {
  252.     if (legend[i] == NULL)
  253.         break;
  254.     strcpy(string, legend[i]);
  255.     j = strlen(string);
  256.     if (j < leglen) {    /* pad string with spaces */
  257.         for (k = j; k < leglen; k++)
  258.         string[k] = ' ';
  259.         string[k] = '\0';
  260.     }
  261.  
  262.     /* pad an extra space */
  263.  
  264.     strcat(string, " ");
  265.     j = strlen(string);
  266.  
  267.     /* insert the ASCII value of the symbol plotted with plpoin() */
  268.  
  269.     string[j] = i + OFFSET;
  270.     string[j + 1] = '\0';
  271.  
  272.     /* plot the string */
  273.  
  274.     plmtex("rv", 1., 1. - (double) (i + 1) / (M + 1), 0., string);
  275.     }
  276.  
  277.     /*  Tell plplot we are done with this page. */
  278.  
  279.     pladv(0);            /* advance page */
  280.  
  281.     /* Don't forget to call PLEND to finish off! */
  282.  
  283.     plend();
  284.     exit(0);
  285. }
  286.  
  287. static int
  288. error(char *str)
  289. {
  290.     fprintf(stderr, "%s\n", str);
  291.     exit(1);
  292. }
  293.